// 1.类装饰器：类装饰器在类声明之前被声明（紧靠着类声明）
// 类装饰器应用于类构造函数，可以用来监视，修改或替换类定义。
// 传入一个参数
// 普通装饰器
function logClass(params: any) {
  console.log(params)
  // params就是当前类
  params.prototype.apiUrl = '动态扩展属性'
}
@logClass
class HttpClient {
  constructor() {
    console.log('我是一个run方法')
  }
  getData() {

  }
}
var http: any = new HttpClient()

console.log(http.apiUrl)  //动态扩展属性

// 装饰器工厂(可传参)
function logClass2(params: string) {
  return function (target: any) {
    console.log(target)
    console.log(params)
    target.prototype.apiUrl = params
  }
}
// @logClass2('hello')
@logClass2('http://www.itying.com/api')
class HttpClient2 {
  constructor() {

  }
  getData() {

  }
}
var http2: any = new HttpClient()
console.log(http2.apiUrl)


/**
 * 类装饰器
 *  重载构造函数
 *  类装饰器表达式会在运行时被当作函数调用，类构造函数作为其唯一的参数。
 *  如果类装饰器返回一个值，它会使用提供的构造函数来替换类的声明
 */
function logClass3(target: any) {
  console.log(target);
  return class extends target {
    apiUrl: any = '我是修改后的数据';
    getData() {
      console.log(this.apiUrl)
    }
  }
}
@logClass3
class HttpClient3 {
  public apiUrl: string | undefined;
  constructor() {
    this.apiUrl = '我是构造函数里的apiUrl';
  }
  getData() {
    this.apiUrl = this.apiUrl + '-------';
    console.log(this.apiUrl);
  }
}
var http3 = new HttpClient3();